package com.jieao.template.common.util;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Map;
import java.util.TimeZone;

/**
 * 使用Jackson完成JSON操作
 * ObjectMapper是线程安全的，可以作为并推荐作为单例使用
 * 注意，把对象转换成json字符串时要保证对象中不存在循环（递归）引用，如A引用B，而B引用同一个A
 * 转换时默认的日期格式是yyyy-MM-dd HH:mm:ss，如果想使用其他格式，需要调用getNewInstance()创建一个新的ObjectMapper对象自己手动设置
 * 值为null的字段不参与生成json格式字符串
 */
public class JsonUtils
{

    private static ObjectMapper objectMapper = new ObjectMapper();

    static
    {
        // 设置转换时日期格式
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        // 字段为null时不参与序列化
        objectMapper.setSerializationInclusion(Include.NON_NULL);
        //json或map转bean忽略没有的字段 与@JsonIgnoreProperties(ignoreUnknown = true) 相同
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

    /**
     * 实体类转换为json字符串
     *
     * @param obj
     * @return
     */
    public static String objectToJson(Object obj)
    {
        try
        {
            return objectMapper.writeValueAsString(obj);
        } catch (JsonProcessingException e)
        {
            throw new RuntimeException(e);
        }
    }


    /**
     * 字符串集合转换为json字符串
     * 为了避免对list元素中的str再次进行处理从而导致转换结果不可用
     *
     * @param strs
     * @return
     */
    public static String objectToJson(Collection<String> strs)
    {
        if (strs == null)
        {
            return "[]";
        }
        StringBuilder builder = new StringBuilder();
        builder.append("[");
        for (String str : strs)
        {
            builder.append(str);
            builder.append(",");
        }
        if (strs.size() > 0)
        {
            builder.deleteCharAt(builder.length() - 1);
        }
        builder.append("]");

        return builder.toString();
    }

    /**
     * 可以转换普通类型，如User、Card等，也可以转换带泛型的类，比如List<T>、Map<K,V>、Xxx<T>等
     *
     * @param jsonStr         json字符串
     * @param beanClass
     * @param parametricTypes 泛型的具体类型
     * @return
     */
    @SuppressWarnings("all")
    public static <T> T stringtoBean(String jsonStr, Class<T> beanClass, Class... parametricTypes)
    {
        try
        {
            if (parametricTypes == null || parametricTypes.length == 0)
            {
                return objectMapper.readValue(jsonStr, beanClass);
            }
            else
            {
                JavaType javaType = objectMapper.getTypeFactory().constructParametricType(beanClass,
                        parametricTypes);
                return objectMapper.readValue(jsonStr, javaType);
            }
        } catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }

    /**
     * 将 Map 转换为 JavaBean
     *
     * @param map
     * @param clazz
     * @return
     */
    public static <T> T map2pojo(Map map, Class<T> clazz)
    {
        return objectMapper.convertValue(map, clazz);
    }

}
